"""Alarm system API endpoints."""

from __future__ import annotations

from datetime import datetime

from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api.deps import get_current_user, get_db
from app.core.config import settings
from app.models.user import User
from app.schemas.alarm import (
    AlarmAcknowledge,
    AlarmHistoryOut,
    AlarmRuleCreate,
    AlarmRuleOut,
    AlarmRuleUpdate,
    BatchAcknowledgeRequest,
    BatchDeleteRequest,
    KeyMetricsOut,
)
from app.services.alarm_service import AlarmService


router = APIRouter()


# ========== Alarm Rules Endpoints ==========


@router.get("/rules", response_model=list[AlarmRuleOut])
async def get_alarm_rules(
    device_id: int | None = Query(None, description="Filter by device ID"),
    include_disabled: bool = Query(False, description="Include disabled rules"),
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> list[AlarmRuleOut]:
    """Get alarm rules list.

    Returns list of alarm rules with optional filters.
    """
    service = AlarmService(session)
    rules = await service.get_rules(device_id=device_id, include_disabled=include_disabled)
    return [AlarmRuleOut.model_validate(r) for r in rules]


@router.post("/rules", response_model=AlarmRuleOut, status_code=status.HTTP_201_CREATED)
async def create_alarm_rule(
    data: AlarmRuleCreate,
    session: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> AlarmRuleOut:
    """Create new alarm rule.

    Requires authentication. The rule will be associated with the current user.
    """
    service = AlarmService(session)
    rule = await service.create_rule(data, user_id=current_user.id)
    await session.commit()
    return AlarmRuleOut.model_validate(rule)


@router.patch("/rules/{rule_id}", response_model=AlarmRuleOut)
@router.put("/rules/{rule_id}", response_model=AlarmRuleOut)
async def update_alarm_rule(
    rule_id: int,
    data: AlarmRuleUpdate,
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> AlarmRuleOut:
    """Update alarm rule (enable/disable, change threshold, etc.)."""
    service = AlarmService(session)
    rule = await service.update_rule(rule_id, data)
    await session.commit()
    return AlarmRuleOut.model_validate(rule)


@router.get("/rules/{rule_id}", response_model=AlarmRuleOut)
async def get_alarm_rule(
    rule_id: int,
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> AlarmRuleOut:
    """Retrieve a single alarm rule by ID."""
    service = AlarmService(session)
    rule = await service.get_rule(rule_id)
    return AlarmRuleOut.model_validate(rule)


@router.post("/rules/batch-delete")
async def batch_delete_rules(
    data: BatchDeleteRequest,
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> dict[str, int]:
    """Batch delete alarm rules."""
    service = AlarmService(session)
    result = await service.batch_delete_rules(data)
    await session.commit()
    return result


@router.delete("/rules/{rule_id}", status_code=status.HTTP_204_NO_CONTENT, response_class=Response)
async def delete_alarm_rule(
    rule_id: int,
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> Response:
    """Delete a single alarm rule."""
    service = AlarmService(session)
    await service.delete_rule(rule_id)
    await session.commit()
    return Response(status_code=status.HTTP_204_NO_CONTENT)


# ========== Alarm History Endpoints ==========


@router.get("/history", response_model=list[AlarmHistoryOut])
async def get_alarm_history(
    device_id: int | None = Query(None, description="Filter by device ID"),
    severity: str | None = Query(None, description="Filter by severity"),
    acknowledged: bool | None = Query(None, description="Filter by acknowledgment status"),
    start_date: datetime | None = Query(None, description="Start date filter"),
    end_date: datetime | None = Query(None, description="End date filter"),
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> list[AlarmHistoryOut]:
    """Get alarm history with optional filters.

    Returns list of alarm history records.
    """
    service = AlarmService(session)
    history = await service.get_alarm_history(
        device_id=device_id,
        severity=severity,
        acknowledged=acknowledged,
        start_date=start_date,
        end_date=end_date,
    )
    return [AlarmHistoryOut.model_validate(h) for h in history]


@router.post("/history/{alarm_id}/acknowledge", response_model=AlarmHistoryOut)
async def acknowledge_alarm(
    alarm_id: int,
    payload: AlarmAcknowledge,
    session: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> AlarmHistoryOut:
    """Acknowledge a single alarm.

    Marks the alarm as acknowledged by the current user.
    """
    service = AlarmService(session)
    alarm = await service.acknowledge_alarm(alarm_id, user_id=current_user.id, note=payload.note)
    await session.commit()
    return AlarmHistoryOut.model_validate(alarm)


@router.post("/batch-acknowledge")
async def batch_acknowledge_alarms(
    data: BatchAcknowledgeRequest,
    session: AsyncSession = Depends(get_db),
    current_user: User = Depends(get_current_user),
) -> dict[str, int]:
    """Batch acknowledge alarms."""
    service = AlarmService(session)
    result = await service.batch_acknowledge_alarms(data, user_id=current_user.id)
    await session.commit()
    return result


# ========== Statistics Endpoints ==========


@router.get("/stats/key-metrics", response_model=KeyMetricsOut)
async def get_key_metrics(
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> KeyMetricsOut:
    """Get key alarm metrics.

    Returns today's count, unacknowledged count, critical count, active rules, and response times.
    """
    service = AlarmService(session)
    return await service.get_key_metrics()


@router.get("/stats/severity-distribution")
async def get_severity_distribution(
    days: int = Query(7, ge=1, le=30, description="Number of days"),
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> dict[str, int | str]:
    """Get alarm count by severity for PieChart."""
    service = AlarmService(session)
    return await service.get_severity_distribution(days=days)


@router.get("/stats/24h-trend")
async def get_24h_trend(
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> dict[str, list[str] | list[dict[str, str | list[int]]]]:
    """Get hourly alarm count for last 24 hours (LineChart)."""
    service = AlarmService(session)
    return await service.get_24h_trend()


@router.get("/stats/top-devices")
async def get_top_devices(
    limit: int = Query(10, ge=1, le=50, description="Number of devices"),
    days: int = Query(7, ge=1, le=30, description="Number of days"),
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> dict[str, int | str]:
    """Get top N devices by alarm count for PieChart."""
    service = AlarmService(session)
    return await service.get_top_devices(limit=limit, days=days)


@router.get("/stats/hourly-distribution")
async def get_hourly_distribution(
    days: int = Query(7, ge=1, le=30, description="Number of days"),
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> dict[str, list[str] | list[dict[str, str | list[int]]]]:
    """Get alarm count by hour of day for last N days (LineChart)."""
    service = AlarmService(session)
    return await service.get_hourly_distribution(days=days)
@router.get("/stats")
async def get_alarm_stats(
    device_id: int | None = Query(None, description="Filter by device ID"),
    hours: int = Query(24, ge=1, le=168, description="Time window in hours"),
    session: AsyncSession = Depends(get_db),
    _: User = Depends(get_current_user),
) -> dict[str, object]:
    """Get aggregated alarm statistics for dashboard cards."""
    service = AlarmService(session)
    stats = await service.get_alarm_stats(device_id=device_id, hours=hours)
    recent = [AlarmHistoryOut.model_validate(item) for item in stats.recent_alarms]
    return {
        "totalAlarms": stats.total_alarms,
        "unacknowledged": stats.unacknowledged,
        "bySeverity": stats.by_severity,
        "recentAlarms": [entry.model_dump(mode="json") for entry in recent],
    }
